package com.youboy.wechatapi.web.controller;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.youboy.wechatapi.domain.message.TextMessage;
import com.youboy.wechatapi.domain.mysql.OperateRecord;
import com.youboy.wechatapi.service.message.MsgTextService;
import com.youboy.wechatapi.service.message.QrcodeService;
import com.youboy.wechatapi.service.record.UserService;
import com.youboy.wechatapi.utils.wechat.MessageUtil;
import com.youboy.wechatapi.utils.wechat.SignUtil;

@Controller
public class IndexController {

	private Logger log = Logger.getLogger(IndexController.class);
	
	@Autowired
	private MsgTextService msgTextService;
	
	@Autowired
	private QrcodeService qrcodeService;
	
	@Autowired
	private UserService userService;

	/**
	 * 确认请求来自微信服务器
	 * 
	 * @param model
	 * @param signature 微信加密签名
	 * @param timestamp 时间戳
	 * @param nonce 随机数
	 * @param echostr  随机字符串
	 * @return
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET, produces = { "text/html;charset=utf-8" })
	@ResponseBody
	public String doGet(Model model,
			@RequestParam(value = "signature") String signature,
			@RequestParam(value = "timestamp") String timestamp,
			@RequestParam(value = "nonce") String nonce,
			@RequestParam(value = "echostr") String echostr) {
		// return "forward:/user/list";
		// return "redirect:/user/list";
		// 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
		if (SignUtil.checkSignature(signature, timestamp, nonce)) {
			log.debug("[signature:" + signature + "][timestamp:" + timestamp + "]"
					+ "[nonce:" + nonce + "][echostr:" + echostr + "]首次效验成功！！");
			return echostr;
		}
		return null;
	}

	/**
	 * 处理微信服务器发来的消息
	 */
	@RequestMapping(value = "/", method = RequestMethod.POST, produces = { "text/html;charset=utf-8" })
	@ResponseBody
	public String doPost(HttpServletRequest request) throws ServletException, IOException {
		// 将请求、响应的编码均设置为UTF-8（防止中文乱码）

		Map<String, String> requestMap = new HashMap<String, String>();
		try {
			requestMap = MessageUtil.parseXml(request);
		} catch (Exception e) {
			log.error("post message receive fial, message convert to map error !", e);
		}
		
		if(requestMap == null || requestMap.size() == 0){
			log.error("post message receive fial, the requestMap is empty !");
			return "";
		}
		
		// 发送方帐号（open_id）
		String fromUserName = requestMap.get("FromUserName");
		// 公众帐号
		String toUserName = requestMap.get("ToUserName");
		// 消息类型
		String msgType = requestMap.get("MsgType");
		// 默认回复此文本消息
		TextMessage textMessage = new TextMessage();
		textMessage.setFromUserName(toUserName);
		textMessage.setToUserName(fromUserName);
		textMessage.setMsgType(MessageUtil.REQ_MESSAGE_TYPE_TEXT);
		textMessage.setCreateTime(new Date().getTime());
		
		String respMessage = null;
		// 文本消息
		if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
			// 接收用户发送的文本消息内容
			String content = requestMap.get("Content");
			try {
				respMessage = msgTextService.receiveMsgText(fromUserName, toUserName, content);
			} catch (Exception e) {
				log.error("get respMessage error !", e);
			}
		}
		// 图片消息  
        else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {  
        	textMessage.setContent("您给我发送的是图片消息！");
        	respMessage = MessageUtil.textMessageToXml(textMessage);
        } // 地理位置消息  
        else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {  
        	textMessage.setContent("您给我发送的是地理位置消息 ！");
        	respMessage = MessageUtil.textMessageToXml(textMessage);
        }  
        // 链接消息  
        else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {
        	textMessage.setContent("您给我发送的是链接消息  ！");
        	respMessage = MessageUtil.textMessageToXml(textMessage);
        }  
        // 音频消息  
        else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {
        	textMessage.setContent("您给我发送的是音频消息 ！");
        	respMessage = MessageUtil.textMessageToXml(textMessage);
        } 
		// 事件推送  
        else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
        	String eventType = requestMap.get("Event");
        	respMessage = this.getEventMsg(fromUserName, toUserName, eventType, requestMap);
        }
		
		// 调用核心业务类接收消息、处理消息
		//respMessage = msgTextService.receiveMessage(requestMap);
		//String respMessage = CoreService.processRequest(request);
		// 响应消息
		//log.info("return message is 【"+ respMessage+"】");
		return respMessage;
	}
	
	/**
	 * 处理事件推送
	 * @param fromUserName
	 * @param toUserName
	 * @param eventType
	 * @param requestMap
	 * @return
	 */
	private String getEventMsg(String fromUserName, String toUserName, String eventType
			,Map<String, String> requestMap){
		// 事件类型
		//String eventType = requestMap.get("Event");
		TextMessage textMessage = new TextMessage();
		String respMessage = null;
		
		StringBuilder eventLog = new StringBuilder();
		eventLog.append("[openid:").append(fromUserName).append("]");
		eventLog.append("[Event:").append(eventType).append("]");
		
		// 订阅
		if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
			textMessage.setToUserName(fromUserName);
			textMessage.setFromUserName(toUserName);
			textMessage.setCreateTime(new Date().getTime());
			textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);

			String helpMsg = null;

			//生成关注后的提升信息
			try {
				helpMsg = msgTextService.getHelpMsg(null, fromUserName);
			} catch (Exception e) {
				log.error(eventLog.append(" get helpMsg error").toString(), e);
			}
			textMessage.setContent(helpMsg);
			// 将文本消息对象转换成xml字符串
			respMessage = MessageUtil.textMessageToXml(textMessage);
			log.info("===== [ opneid:" + fromUserName + "] subscribe success !=====");
			
			/***************************************************************************/
			
			//如果是通过二维码扫描进行关注则进行记录
			String eventKey = requestMap.get("EventKey");
			
			eventLog.append("[EventKey:").append(eventKey).append("]");
			
			Integer scene_id = -1;
			String ticket = null;
			//如果是二维码扫描则进行记录
			if(StringUtils.isNotBlank(eventKey)){
				scene_id = Integer.valueOf(eventKey.replace("qrscene_", ""));
				
				if(scene_id != null){
					ticket = requestMap.get("Ticket");
					eventLog.append("[scene_id:").append(scene_id).append("]");
					eventLog.append("[Ticket:").append(ticket).append("]");
				}
			}
			
			//保存订阅记录
			OperateRecord qrcode = new OperateRecord(toUserName, fromUserName, eventType, scene_id, ticket, new Date());
			try {
				qrcodeService.save(qrcode);
				log.info(eventLog.append(" SUBSCRIBE save qrcodeRecord success !").toString());
			} catch (Exception e) {
				log.error(eventLog.append(" SUBSCRIBE save qrcodeRecord error !").toString(), e);
			}

			//拉取用户信息，并保存
			try {
				userService.saveUserInfo(fromUserName);
			} catch (Exception e) {
				log.error(eventLog.append(" SUBSCRIBE svae userInfo error !").toString(), e);
			}
		}
		// 取消订阅
		else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
			// TODO 取消订阅后用户再收不到公众号发送的消息，因此不需要回复消息
			Integer scene_id = -2;
			
			//保存订阅记录
			OperateRecord qrcode = new OperateRecord(toUserName, fromUserName, eventType, scene_id, null, new Date());
			try {
				qrcodeService.save(qrcode);
				log.info(eventLog.append("  UNSUBSCRIBE save qrcodeRecord success !").toString());
			} catch (Exception e) {
				log.error(eventLog.append(" UNSUBSCRIBE save qrcodeRecord error !").toString(), e);
			}
		}
		// 自定义菜单按钮点击事件
		else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
			
		}
		// 自定义菜单链接点击事件
		else if (eventType.equals(MessageUtil.EVENT_TYPE_VIEW)) {
			
		}
		// 二维码扫描
		else if (eventType.equals(MessageUtil.EVENT_TYPE_SCAN)) {
			String eventKey = requestMap.get("EventKey");

			String ticket = requestMap.get("Ticket");
			
			eventLog.append("[EventKey:").append(eventKey).append("]");
			
			//如果是二维码扫描则进行记录
			if(StringUtils.isNotBlank(eventKey)){
				Integer scene_id = Integer.valueOf(eventKey);
				
				if(scene_id != null){
					eventLog.append("[scene_id:").append(scene_id).append("]");
					OperateRecord qrcode = new OperateRecord(toUserName, fromUserName, eventType, scene_id, ticket, new Date());
					try {
						qrcodeService.save(qrcode);
						log.info(eventLog.append(" SCAN save qrcodeRecord success !").toString());
					} catch (Exception e) {
						log.error(eventLog.append(" SCAN save qrcodeRecord error !").toString(), e);
					}
					
				}
			}
			
		}
		// 其他事件
		else {
			
		}
		return respMessage;
	}
	
}
